package cn.wolfcode.shop.service;

import cn.wolfcode.shop.domain.ShopCar;
import cn.wolfcode.shop.domain.UserAddress;
import cn.wolfcode.shop.domain.UserLogin;
import cn.wolfcode.shop.domian.Invoice;
import cn.wolfcode.shop.domian.OrderAction;
import cn.wolfcode.shop.domian.OrderInfo;
import cn.wolfcode.shop.domian.OrderProduct;
import cn.wolfcode.shop.exception.UserException;
import cn.wolfcode.shop.mapper.InvoiceMapper;
import cn.wolfcode.shop.mapper.OrderActionMapper;
import cn.wolfcode.shop.mapper.OrderInfoMapper;
import cn.wolfcode.shop.mapper.OrderProductMapper;
import cn.wolfcode.shop.qo.OrderQueryObject;
import cn.wolfcode.shop.qo.PageResult;
import cn.wolfcode.shop.util.IdGenerateUtil;
import cn.wolfcode.shop.util.RedisConstants;
import cn.wolfcode.shop.vo.CreateOrderVo;
import cn.wolfcode.shop.vo.OrderStatusChangeVo;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service@Transactional
public class OrderInfoServiceImpl implements IOrderInfoService {
    @Autowired
    private InvoiceMapper invoiceMapper;
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderProductMapper orderProductMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private OrderActionMapper orderActionMapper;

    @Reference
    private IUserAddressService userAddressService;

    @Override
    public OrderInfo generateOrder(Long userId, CreateOrderVo vo) {
        //创建订单对象，设置用户id
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userId);
        //生成订单编号(在分布式环境下保证编号是唯一)
        orderInfo.setOrderSn(IdGenerateUtil.get().nextId()+"");
        //通过用户收货地址id获取用户收货地址对象，并设置到订单信息中
        UserAddress userAddress = userAddressService.get(vo.getUserAddressId());
        orderInfo.setConsignee(userAddress.getConsignee());
        orderInfo.setPhone(userAddress.getPhone());
        orderInfo.setCountry(userAddress.getCountry());
        orderInfo.setProvince(userAddress.getProvince());
        orderInfo.setCity(userAddress.getCity());
        orderInfo.setDistrict(userAddress.getDistrict());
        orderInfo.setAddress(userAddress.getAddress());
        orderInfo.setZipcode(userAddress.getZipcode());
        //设置订单的其他信息，比如订单状态，收货状态，物流状态，下单时间等
        orderInfo.setOrderStatus(0);
        orderInfo.setFlowStatus(0);
        orderInfo.setPayStatus(0);
        orderInfo.setPayType(vo.getPay().getPayType());
        orderInfo.setOrderTime(new Date());
        //设置订单总金额
        orderInfo.setOrderAmount(new BigDecimal("0.00"));
        //插入该订单
        orderInfoMapper.insert(orderInfo);
        //获取购物车商品列表遍历，并生成订单商品明细
        //car的信息转移到订单商品明细中
        //通过skuId获取sku对象，并设置价格
        //计算订单商品明细中的商品小计
        //把订单商品明细中的商品小计累加到订单总额中
        //插入该订单商品明细
        //遍历sku属性集合，并设置到订单商品明细属性对象中，插入该订单商品明细属性数据
        //从新设置订单总额
        List<String> shopChaKeys = new ArrayList<>();
        for (Long productSkuId : vo.getProductSkuIds()) {
            String shopCarKey = MessageFormat.format(RedisConstants.SHOP_CAR, userId, productSkuId);
            shopChaKeys.add(shopCarKey);
            ShopCar shopCar = (ShopCar) redisTemplate.opsForValue().get(shopCarKey);
            if (shopCar == null) {
                throw new UserException("非法操作");
            }
            OrderProduct orderProduct = new OrderProduct();
            orderProduct.setOrderId(orderInfo.getId());
            orderProduct.setProductImg(shopCar.getProductImage());
            orderProduct.setProductName(shopCar.getProductName());
            orderProduct.setProductNumber(shopCar.getNumber());
            orderProduct.setProductPrice(shopCar.getPrice());
            orderProduct.setSkuId(shopCar.getProductSkuId());
            orderProduct.setSkuType(shopCar.getSkuPropertyString());
            orderProduct.setTotalPrice(shopCar.getNumber().multiply(shopCar.getPrice()));
            orderProductMapper.insert(orderProduct);
            orderInfo.setOrderAmount(orderInfo.getOrderAmount().add(orderProduct.getTotalPrice()));
        }
        //更新该订单
        orderInfoMapper.updateByPrimaryKey(orderInfo);
        //判断是否需要开发票，如果要则,设置发票人和发票对应的订单，并插入发票信息
        if (vo.getInvoice() != null) {
            vo.getInvoice().setOrderId(orderInfo.getId());
            vo.getInvoice().setUserId(userId);
            invoiceMapper.insert(vo.getInvoice());
        }
        //记录订单的操作日志
        OrderAction orderAction = new OrderAction();
        orderAction.setActionNote("创建订单");
        orderAction.setActionPlace("后台");
        orderAction.setActionTime(new Date());
        orderAction.setActionUser("后台管理员");
        orderAction.setFlowStatus(orderInfo.getFlowStatus());
        orderAction.setOrderId(orderInfo.getId());
        orderAction.setOrderStatus(orderInfo.getOrderStatus());
        orderAction.setPayStatus(orderInfo.getPayStatus());
        orderActionMapper.insert(orderAction);
        //判断有无购物车id，如果有则删除购物车信息
        redisTemplate.delete(shopChaKeys);
        return orderInfo;
    }

    @Override
    public PageResult query(OrderQueryObject qo) {
        int count = orderInfoMapper.queryCount(qo);
        if(count == 0){
            return PageResult.empty();
        }
        List<OrderInfo> orderInfoList = orderInfoMapper.queryList(qo);

        return new PageResult(orderInfoList,count,qo.getCurrentPage(),qo.getPageSize());
    }

    @Override
    public OrderInfo getById(Long id) {
        return orderInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public void changeStatus(String note, Integer changeType, Long orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectByPrimaryKey(orderId);
        if (orderInfo == null) {
            throw new UserException("非法操作");
        }
        switch (changeType){
            case 1:orderInfo.setOrderStatus(1);break;
            case 2:orderInfo.setFlowStatus(1);break;
            case 4:
                System.out.println("商城提供售后服务");break;
            case 3:orderInfo.setFlowStatus(4);break;
            default:
                System.out.println("商城提供售后服务");break;
        }
        orderInfoMapper.updateByPrimaryKey(orderInfo);
        //记录订单的操作日志
        OrderAction orderAction = new OrderAction();
        orderAction.setActionNote(note);
        orderAction.setActionPlace("后台");
        orderAction.setActionTime(new Date());
        orderAction.setActionUser("后台管理员");
        orderAction.setFlowStatus(orderInfo.getFlowStatus());
        orderAction.setOrderId(orderInfo.getId());
        orderAction.setOrderStatus(orderInfo.getOrderStatus());
        orderAction.setPayStatus(orderInfo.getPayStatus());
        orderActionMapper.insert(orderAction);
    }

    @Override
    public OrderInfo changeStatus(OrderStatusChangeVo orderStatusChangeVo) {
        OrderInfo orderInfo = orderInfoMapper.selectByPrimaryKey(orderStatusChangeVo.getOrderId());
        if (orderInfo == null) {
            throw new UserException("非法操作");
        }
        switch (orderStatusChangeVo.getChangeType()){
            case 5:orderInfo.setOrderStatus(2);orderInfo.setFlowStatus(2);break;
            default:
                System.out.println("商城提供售后服务");break;
        }
        orderInfoMapper.updateByPrimaryKey(orderInfo);
        //记录订单的操作日志
        OrderAction orderAction = new OrderAction();
        orderAction.setActionNote(orderStatusChangeVo.getNote());
        orderAction.setActionPlace("前台");
        orderAction.setActionTime(new Date());
        orderAction.setActionUser(orderStatusChangeVo.getUserName());
        orderAction.setFlowStatus(orderInfo.getFlowStatus());
        orderAction.setOrderId(orderInfo.getId());
        orderAction.setOrderStatus(orderInfo.getOrderStatus());
        orderAction.setPayStatus(orderInfo.getPayStatus());
        orderActionMapper.insert(orderAction);
        return orderInfo;
    }
}
